package com.xr.system.controller;

import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.xr.common.annotation.SystemLog;
import com.xr.common.constants.RedisConstant;
import com.xr.common.entity.SimpleUser;
import com.xr.common.enums.LogType;
import com.xr.common.utils.MailPatternMatchUtil;
import com.xr.system.common.base.Result;
import com.xr.system.common.config.mailConfig.MailConf;
import com.xr.system.common.constants.SystemConstant;
import com.xr.system.common.constants.MailConstant;
import com.xr.system.common.utils.ThreadLocalUtil;
import com.xr.system.entity.userModule.LoginInfoVo;
import com.xr.system.entity.userModule.User;
import com.xr.system.service.PermissionService;
import com.xr.system.service.UserService;
import com.xr.mail.service.MailUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;

/**
 * 登录相关
 */
@Slf4j
@Validated
@RestController
@RequestMapping("/api/v1/login")
public class LoginController {

	@Resource
	private MailConf mailConf;

	@Resource
	private UserService userService;

	@Resource
	private PermissionService permissionService;

	@Resource
	private MailUtils mailUtils;

	@Resource
	private StringRedisTemplate stringRedisTemplate;

	/**
	 * 登录接口
	 * @param loginInfoVO
	 * @return
	 */
	@SystemLog(module = "用户模块", type = LogType.LOGIN, description = "用户登录")
	@PostMapping("/login")
	public Result<Object> login(@Validated @RequestBody LoginInfoVo loginInfoVO) {
		SaSession tokenSession = StpUtil.getTokenSession();
		Object attribute = tokenSession.get(SystemConstant.CAPTCHA_SESSION_KEY);
		if (attribute == null) {
			return Result.error("验证码已失效，请刷新页面后重试！");
		}
		if (!StrUtil.equalsIgnoreCase((CharSequence) attribute, loginInfoVO.getVerificationCode())) {
			return Result.error("验证码不正确！");
		}
		tokenSession.delete(SystemConstant.CAPTCHA_SESSION_KEY);
		LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery();
		wrapper.eq(User::getAccount, loginInfoVO.getAccount()).eq(User::getEnable, true);
		User user = userService.getOne(wrapper);
		if (user == null) {
			return Result.error("账户或密码错误");
		}
		String userEmail = user.getEmail();
		String password = user.getPassword();
		Assert.notBlank(password, "密码不能为空");
		boolean flag = DigestUtil.bcryptCheck(loginInfoVO.getPassword(), password);
		if (flag) {
			Long userId = user.getId();
			StpUtil.login(userId);
			String userName = user.getName();
			SimpleUser simpleUser = new SimpleUser();
			simpleUser.setUserId(userId);
			simpleUser.setUserName(userName);
			stringRedisTemplate.opsForValue().set(RedisConstant.CURRENT_LOGIN_USER_KEY, JSONUtil.toJsonStr(simpleUser));
			ThreadLocalUtil.setUser(user);
			if ("true".equalsIgnoreCase(mailConf.getIsEnabled()) && null != userEmail
					&& MailPatternMatchUtil.isMatchedOrNot(userEmail)) {
				// Lambda表达式 创建异步线程完成邮件通知
				new Thread(() -> {
					try {
						mailUtils.sendMail(userEmail, MailConstant.MAIL_TITLE, MailConstant.MAIL_TEXT);
					}
					catch (Exception e) {
						e.printStackTrace();
					}
				}).start();
				/*
				 * // 匿名内部类 创建异步线程完成邮件通知 new Thread(new Runnable() {
				 *
				 * @Override public void run() { try { mailUtils.sendMail(userEmail,
				 * "XrSaTokenCloud系统登录通知", "感谢您对XrSaTokenCloud轻量级微服务开发框架的认可与使用，登录成功！！！");
				 * } catch (Exception e) { e.printStackTrace(); } } }).start();
				 */
			}
			return Result.success(StpUtil.getTokenValue());
		}
		return Result.error("账号或密码错误");
	}

	/**
	 * 获取当前登录人的页面权限
	 */
	@GetMapping("/permission")
	public Result<List<String>> getPermissions() {
		return Result.success(permissionService.getAllPermissionUrlByUserId());
	}

	/**
	 * 获取当前登录人的按钮权限
	 */
	@GetMapping("/btnPermission")
	public Result<List<String>> getBtnPermission() {
		return Result.success(permissionService.getAllBtnPermissionByUserId());
	}

	/**
	 * 注销登录
	 */
	@SystemLog(module = "用户模块", type = LogType.LOGOUT, description = "用户注销")
	@GetMapping("/signOut")
	public Result<Object> signOut() {
		StpUtil.logout();
		stringRedisTemplate.delete(RedisConstant.CURRENT_LOGIN_USER_KEY);
		return Result.success();
	}

}
